/**
 * 该场景固定长宽: 1920 x 1080
 * 
 * HTML 设置方案
 * #main
 *   div#panel (1920x1080)
 *   canvas#coreBg (中间那块)
 *   div#desk (中间那块)
 *   div#titleFrame (标题那小块地方)
 *   div#tips (计时器启动动画、玩家结束后的记分条)
 */

import events from '../view/v4/events';

import ScoreBoard from '../compute/v4/scoreboard';
import { Panel } from '../view/v4/panel'

function createScene(context) {
	let t = new App(context);
	global.app = t;
	let scene = new context.Scene({
		require : ['zrender'],
		init : (libs) => t.init(libs),
		destroy : () => t.destroy(),
		collectInfo : () => t.collectInfo(),
		onMessage : (key, data) => t.onMessage(key, data),
	});
	t.sendStatus = scene.sendStatus;
	return scene;
};

class App {
	constructor(context) {
		this.context = context;
		this.scoreBoard = new ScoreBoard();
	}

	zrender = null;
	zr = null;
	require = ['zrender'];

	init(libs) {
		const { scoreBoard } = this;

		const panel = this.panel = new Panel({
			context : this.context,
			zrender : libs.zrender,
			scoreBoard,
		});

		scoreBoard.onPlayerNameUpdate =
			(playerNo, name) => panel.emit(events.PLAYER_NAME_UPDATED, { playerNo, name });
		scoreBoard.onTitleUpdate = (title) => panel.emit(events.TITLE_UPDATED, { title });
		scoreBoard.onTimerStart = () => panel.emit(events.TIMER_START);
		scoreBoard.onTimerPlay = () => panel.emit(events.TIMER_PLAY);
		scoreBoard.onTimerStop = () => panel.emit(events.TIMER_STOP);
		scoreBoard.onTimerPause = () => panel.emit(events.TIMER_PAUSE);
		scoreBoard.onTimerReset = () => panel.emit(events.TIMER_RESET);

		scoreBoard.onPlayerFinish = (playerNo) => panel.emit(events.PLAYER_FINISH, {playerNo});
		scoreBoard.onPlayerStart = (playerNo) => panel.emit(events.PLAYER_START, {playerNo});
		scoreBoard.onPlayerStop = (playerNo) => panel.emit(events.PLAYER_STOP, {playerNo});
		scoreBoard.onPlayerReset = (playerNo) => panel.emit(events.PLAYER_RESET, {playerNo});

		panel._init();
	}

	/*
	 * 收集状态数据
	 */
	collectInfo() {
		const {scoreBoard: s} = this;
		const p1 = s.findPlayer(1);
		const p2 = s.findPlayer(2);
		const p3 = s.findPlayer(3);
		const p4 = s.findPlayer(4);

		return {
			screen : {
				p1Name : p1.name,
				p2Name : p2.name,
				p3Name : p3.name,
				p4Name : p4.name,
				p1Score : p1.score,
				p2Score : p2.score,
				p3Score : p3.score,
				p4Score : p4.score,
				p1Cancel : p1.isWaivered(),
				p2Cancel : p2.isWaivered(),
				p3Cancel : p3.isWaivered(),
				p4Cancel : p4.isWaivered(),
				p1Preset : p1.preset,
				p2Preset : p2.preset,
				p3Preset : p3.preset,
				p4Preset : p4.preset,
				title : s.title
			},
			timer : {
				playing : s.timer.started(),
				pause : (s.timer.isPaused() || s.timer.isFinished()) ? s.timer.delta : 0,
				baseTime : s.timer.baseTime
			},
			version : 1
		};
	}

	/* **********
	 * 状态控制 *
	 ********** */

	onMessage (name, arg) {
		switch (name) {
		case 'player_name_change': // 文本改变
			this.onPlayerNameChange(arg);
			break;
		case 'title_change': // 文本改变
			this.scoreBoard.updateTitle(arg.title);
			break;
		case 'timer_start': {
			this.scoreBoard.timerStart();
		} break;
		case 'timer_stop':
			this.scoreBoard.timerStop();
			break;
		case 'timer_pause':
			this.scoreBoard.timerPause();
			break;
		case 'timer_reset':
			this.scoreBoard.timerReset();
			break;
		case 'timer_undoPause': case 'timer_undo_pause':
			this.scoreBoard.timerUndoPause();
			break;
		case 'timer_record':
			// arg = {player:1, time:1000}  指定结束时间 1 秒
			// arg = {player:1}  1P 正常结束
			this.onTimerRecord(arg.player, arg.time);
			break;
		case 'timer_undoRecord': case 'timer_undo_record':
			// arg = {player:1}  1P 正常结束
			this.onTimerUndoRecord(arg.player);
			break;
		case 'waiver': // 某个玩家说要弃权 / 恢复资格
			// 示例输入 : {"player":1, "attend":false} - P1 弃权
			this.onWaiver(arg.player, arg.attend);
			break;
		case 'preset_score': // 鸽鸽新需求, 要某个玩家到某个时间点就自动停下来
			this.presetScore(arg.player, arg.score);
			break;
		default:
			console.log("收到命令:", name);
			console.log(arg);
			return;
		}
		this.sendStatus();
	}

	onPlayerNameChange(o) {
		if (o.p1Name != undefined && typeof(o.p1Name) === 'string') {
			this.scoreBoard.updatePlayerName(1, o.p1Name);
		}
		if (o.p2Name != undefined && typeof(o.p2Name) === 'string') {
			this.scoreBoard.updatePlayerName(2, o.p2Name);
		}
		if (o.p3Name != undefined && typeof(o.p3Name) === 'string') {
			this.scoreBoard.updatePlayerName(3, o.p3Name);
		}
		if (o.p4Name != undefined && typeof(o.p4Name) === 'string') {
			this.scoreBoard.updatePlayerName(4, o.p4Name);
		}
	}

	onTimerRecord(playerNo, time) {
		if (typeof(playerNo) != 'number') {
			console.error('收到玩家记录信号, 但是 player 参数错误: ', arg);
			return;
		}
		if (time == null) {
			this.scoreBoard.doRecord(playerNo);
			return;
		}
		if (typeof(time) != 'number' || time < 0) {
			console.error('收到玩家记录信号, 但是 time 参数错误: ', arg);
			return;
		}
		this.scoreBoard.doRecord(playerNo, time);
	}

	onTimerUndoRecord(playerNo) {
		if (typeof(playerNo) != 'number') {
			console.error('收到玩家撤销记录信号, 但是 player 参数错误: ', arg);
			return;
		}
		this.scoreBoard.undoRecord(playerNo);
	}

	onWaiver(playerNo, attend) {
		if (typeof(playerNo) != 'number') {
			console.error('收到弃权记录信号, 但是 player 参数错误: ', arg);
			return;
		}
		if (typeof(attend) != 'boolean') {
			console.error('收到弃权记录信号, 但是 attend 参数错误: ', arg);
			return;
		}

		if (attend) {
			this.scoreBoard.undoRecord(playerNo);
		} else {
			this.scoreBoard.waiver(playerNo);
		}
	}

	presetScore(playerNo, score) {
		// 示例输入 : {"player":1, "score":1000} - P1 预设时间为 1 秒.
		// 示例输入 : {"player":1} - P1 删除预设输入.
		const {scoreBoard} = this;
		if (score == null) {
			scoreBoard.removePreset(playerNo);
		} else {
			scoreBoard.preset(playerNo, score)
		}
	}
}

export default createScene;
